package com.zho.dao.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.LockMode;
import org.hibernate.Query;

import com.zho.common.domain.db.PagingInfo;
import com.zho.common.domain.db.SearchResult;
import com.zho.common.utility.Constants;
import com.zho.common.utility.Constants.QueryName;
import com.zho.common.utility.db.SearchItem;
import com.zho.common.utility.db.SearchQueryTemplate;
import com.zho.dao.ICgsCustomerDAO;
import com.zho.domain.bean.CgsCustomer;
import com.zho.domain.model.CustomerCondition;
import com.zho.util.Logit;

/**
 * A data access object (DAO) providing persistence and search support for
 * CgsCustomer entities. Transaction control of the save(), update() and
 * delete() operations can directly support Spring container-managed
 * transactions or they can be augmented to handle user-managed Spring
 * transactions. Each of these methods provides additional information for how
 * to configure it for the desired type of transaction control.
 * 
 * @see com.zho.domain.bean.CgsCustomer
 * @author MyEclipse Persistence Tools
 */

public class CgsCustomerDAO extends BaseHelperDAO implements ICgsCustomerDAO {
	private static final Logit log = Logit.getInstance(CgsCustomerDAO.class);
	// property constants
	public static final String CUSTOMER_NAME = "customerName";
	public static final String PHONE_NUMBER = "phoneNumber";
	public static final String EMAIL_ADDRESS = "emailAddress";
	public static final String COUNTRY_OF_RESIDENCE = "countryOfResidence";
	public static final String ADDRESS = "address";
	public static final String TOWN_CITY = "townCity";
	public static final String COUNTRY = "country";
	public static final String POSTCODE = "postcode";
	public static final String LOGIN_ID = "loginId";
	public static final String PASSWORD = "password";
	public static final String SECURITY_QUESTION = "securityQuestion";
	public static final String ANSWER = "answer";
	public static final String PROMOTION_CODE = "promotionCode";
	public static final String ACTIVE_FLG = "activeFlg";

	protected void initDao() {
		// do nothing
	}

	public void save(CgsCustomer transientInstance) {
		log.debug("saving CgsCustomer instance");
		try {
			getHibernateTemplate().save(transientInstance);
			log.debug("save successful");
		} catch (RuntimeException re) {
			log.error("save failed", re);
			throw re;
		}
	}

	public void delete(CgsCustomer persistentInstance) {
		log.debug("deleting CgsCustomer instance");
		try {
			getHibernateTemplate().delete(persistentInstance);
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
	}

	public CgsCustomer findById(java.lang.String id) {
		log.debug("getting CgsCustomer instance with id: " + id);
		try {
			CgsCustomer instance = null;
			List list = findByProperty("customerId", id);
			if (list != null && list.size() != 0)
				instance = (CgsCustomer)list.get(0);
			return instance;		
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}

	public List findByExample(CgsCustomer instance) {
		log.debug("finding CgsCustomer instance by example");
		try {
			List results = getHibernateTemplate().findByExample(instance);
			log.debug("find by example successful, result size: "
					+ results.size());
			return results;
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}

	public List findByProperty(String propertyName, Object value) {
		log.debug("finding CgsCustomer instance with property: " + propertyName
				+ ", value: " + value);
		try {
			String queryString = "from CgsCustomer as model where model."
					+ propertyName + "= ?";
			return getHibernateTemplate().find(queryString, value);
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			throw re;
		}
	}

	public List findByCustomerName(Object customerName) {
		return findByProperty(CUSTOMER_NAME, customerName);
	}

	public List findByPhoneNumber(Object phoneNumber) {
		return findByProperty(PHONE_NUMBER, phoneNumber);
	}

	public CgsCustomer findByEmailAddress(Object emailAddress) {
		List<CgsCustomer> list = findByProperty(EMAIL_ADDRESS, emailAddress);
		if (list != null && list.size() != 0) 
			return list.get(0);
		else return null;
	}

	public List findByCountryOfResidence(Object countryOfResidence) {
		return findByProperty(COUNTRY_OF_RESIDENCE, countryOfResidence);
	}

	public List findByAddress(Object address) {
		return findByProperty(ADDRESS, address);
	}

	public List findByTownCity(Object townCity) {
		return findByProperty(TOWN_CITY, townCity);
	}

	public List findByCountry(Object country) {
		return findByProperty(COUNTRY, country);
	}

	public List findByPostcode(Object postcode) {
		return findByProperty(POSTCODE, postcode);
	}

	public List findByLoginId(Object loginId) {
		return findByProperty(LOGIN_ID, loginId);
	}

	public List findByPassword(Object password) {
		return findByProperty(PASSWORD, password);
	}

	public List findBySecurityQuestion(Object securityQuestion) {
		return findByProperty(SECURITY_QUESTION, securityQuestion);
	}

	public List findByAnswer(Object answer) {
		return findByProperty(ANSWER, answer);
	}

	public List findByPromotionCode(Object promotionCode) {
		return findByProperty(PROMOTION_CODE, promotionCode);
	}

	public List findByActiveFlg(Object activeFlg) {
		return findByProperty(ACTIVE_FLG, activeFlg);
	}

	public List findAll() {
		log.debug("finding all CgsCustomer instances");
		try {
			String queryString = "from CgsCustomer";
			return getHibernateTemplate().find(queryString);
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		}
	}

	public CgsCustomer merge(CgsCustomer detachedInstance) {
		log.debug("merging CgsCustomer instance");
		try {
			CgsCustomer result = (CgsCustomer) getHibernateTemplate().merge(
					detachedInstance);
			log.debug("merge successful");
			return result;
		} catch (RuntimeException re) {
			log.error("merge failed", re);
			throw re;
		}
	}

	public void attachDirty(CgsCustomer instance) {
		log.debug("attaching dirty CgsCustomer instance");
		try {
			getHibernateTemplate().saveOrUpdate(instance);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

	public void attachClean(CgsCustomer instance) {
		log.debug("attaching clean CgsCustomer instance");
		try {
			getHibernateTemplate().lock(instance, LockMode.NONE);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

	/**
	 * @param
	 * @return
	 * @auth ho.viet.duan
	 * @CrDate Dec 19, 2011
	 */
	public SearchResult<CgsCustomer> listCgsCustomer(
			CustomerCondition condition, PagingInfo pagingInfo,
			final String orderColumn) {
		SearchResult<CgsCustomer> result = null;

		// Prepare
		SearchQueryTemplate searchQueryTemplate = new SearchQueryTemplate(
				orderColumn, pagingInfo);
		searchQueryTemplate
				.setQueryString("select cgsCustomer from CgsCustomer cgsCustomer ");
		searchQueryTemplate
				.setCountQueryString("select count(*) from CgsCustomer cgsCustomer ");

		// Add where condition
		if (condition != null) {

			if (!StringUtils.isEmpty(condition.getCustomerId())) {
				String customerId = condition.getCustomerId();
				searchQueryTemplate.addRestriction(new SearchItem("customerId",
						"cgsCustomer.customerId like :customerId", customerId));
			}

			if (!StringUtils.isEmpty(condition.getEmailAddress())) {
				String emailAddress = "%" + condition.getEmailAddress() + "%";
				searchQueryTemplate.addRestriction(new SearchItem(
						"emailAddress",
						"cgsCustomer.emailAddress like :emailAddress",
						emailAddress));
			}

			if (condition.getActiveFlg() != null) {
				searchQueryTemplate.addRestriction(new SearchItem("activeFlg",
						"cgsCustomer.activeFlg = :activeFlg", condition
								.getActiveFlg()));
			}

			if (condition.getDob() != null) {
				searchQueryTemplate.addRestriction(new SearchItem("dob",
						"cgsCustomer.dob = :dob", condition.getDob()));
			}
		}

		result = this.find(searchQueryTemplate);
		return result;
	}

	/**
	 * UpdateGeneral Account Settings
	 * 
	 * @param customerId
	 */
	public void updateProfilePicture(CgsCustomer cgsCustomer) throws Exception {
		try {
			Query query = getSession().getNamedQuery(
					QueryName.CUSTOMER_UPDATE_PROFILE_PICTURE);
			query.setParameter("imagePath", cgsCustomer.getImagePath());
			query.setParameter("updateDate", new Date());
			query.setParameter("customerId", cgsCustomer.getCustomerId());
			query.executeUpdate();

		} catch (RuntimeException re) {
			log.error(re.getMessage(), re);
			throw re;
		}
	}

	/**
	 * Update Profile Picture
	 * 
	 * @param customerId
	 */
	public void updatePassword(CgsCustomer cgsCustomer) throws Exception {
		try {
			Query query = getSession().getNamedQuery(
					QueryName.CUSTOMER_UPDATE_PASSSWORD);
			query.setParameter("password", cgsCustomer.getPassword());
			query.setParameter("updateDate", new Date());
			query.setParameter("customerId", cgsCustomer.getCustomerId());
			query.executeUpdate();

		} catch (RuntimeException re) {
			log.error(re.getMessage(), re);
			throw re;
		}
	}
}